<?php
/**
 * 股票服务类
 * User: Woozee
 * Date: 2021/1/27
 * Time: 22:43
 */

namespace App\Services;

use App\Enum\CacheKeyEnum;
use App\Enum\Stock\ContinueTypeEnum;
use App\Enum\Stock\FinancialReportPeriod;
use App\Models\Stock\Stock;
use App\Responses\Stock\Index\StockConfigResp;
use App\Responses\Stock\Tech\StockPaginationItem;
use App\Responses\Stock\Tech\StockPaginationResp;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;

class StockService extends BaseService
{
    public function __construct()
    {

    }

    /**
     * 获取持续强势/弱势列表
     *
     * @param Request $request
     * @return StockPaginationResp
     */
    public function getContinueList(Request $request): StockPaginationResp
    {
        $days = $request->get('days', 3);
        $startDate = $request->get('start_date');
        $type = $request->get('type', ContinueTypeEnum::STRONG);
        $startDate = empty($startDate) ? Carbon::now()->toDateString() : Carbon::parse($startDate)->toDateString();
        $cacheKey = CacheKeyEnum::getContinueKey($days, $startDate, $type);
//        $cacheKey = 'continuedStrongStocks_20200717_3';
        $tsCodeList = Redis::connection('cache')->lrange($cacheKey, 0, -1);

        return $this->getStockPaginationResp($tsCodeList, $request->get('page'), $request->get('page_size'));
    }

    /**
     * 获取股票配置
     *
     * @return StockConfigResp
     */
    public function getConfig(): StockConfigResp
    {
        $config = config('stock');

        return new StockConfigResp($config);
    }

    /**
     * 获取业绩高增长股票列表
     *
     * @param Request $request
     * @return StockPaginationResp
     */
    public function getGrowthList(Request $request): StockPaginationResp
    {
        $growth = $request->get('growth', 30);
        $duration = $request->get('duration', 2);
        $period = $request->get('period', FinancialReportPeriod::ONE_QUARTERLY);
        $cacheKey = CacheKeyEnum::getGrowthKey($period, $growth, $duration, Carbon::now()->year);
        $tsCodeList = Redis::connection('cache')->lrange($cacheKey, 0, -1);

        return $this->getStockPaginationResp($tsCodeList, $request->get('page'), $request->get('page_size'));
    }

    /**
     * 获取股票分页数据响应
     *
     * @param array $tsCodeList
     * @param int $page
     * @param int $pageSize
     * @return StockPaginationResp
     */
    protected function getStockPaginationResp(array $tsCodeList, int $page, int $pageSize): StockPaginationResp
    {
        $resp = new StockPaginationResp();
        if ($tsCodeList) {
            $list = [];
            $stockList = Stock::whereIn('ts_code', $tsCodeList)->paginate($pageSize, ['*'], 'page', $page);
            foreach ($stockList as $stock) {
                $list[] = StockPaginationItem::fromItem($stock);
            }
            $resp->total = $stockList->total();
            $resp->list = $list;
        } else {
            $resp->total = 0;
            $resp->list = [];
        }

        return $resp;
    }
}
